home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / snws190s.zip / EXPIRE.C < prev    next >
Text File  |  1992-03-19  |  11KB  |  341 lines

  1. /*
  2.                               Simple NEWS
  3.  
  4.     EXPIRE - expire news database articles by number of days since rx'd
  5.  
  6.  
  7.     Copyright (C) 1991  John McCombs, PO Box 2708, Christchurch, NEW ZEALAND
  8.                         john@ahuriri.gen.nz
  9.  
  10.     This program is free software; you can redistribute it and/or modify
  11.     it under the terms of the GNU General Public License, version 1, as
  12.     published by the Free Software Foundation.
  13.  
  14.     This program is distributed in the hope that it will be useful,
  15.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.     GNU General Public License for more details.
  18.  
  19.     See the file COPYING, which contains a copy of the GNU General
  20.     Public License.
  21.  
  22.  
  23.     USAGE:  expires <days>
  24.  
  25.  */
  26.  
  27. #include "defs.h"
  28. #include <io.h>
  29. #include "expire.h"
  30.  
  31. INFO my_stuff;
  32.  
  33.  
  34. /*------------------------------- main --------------------------------*/
  35. void main(int argc, char *argv[])
  36. {
  37.     /*
  38.      *  This routine expires the news database thus:
  39.      *    - copy the index and text files into new ones, omitting the old ones
  40.      *    - update the article counters
  41.      *    - delete the old articles and rename the new files
  42.      *    - print the totals
  43.      *
  44.      *  TODO: It's too big a hunk break it up
  45.      */
  46.  
  47.     ACTIVE *gp, *head;
  48.     char   *fn, buf[256], buf2[256], subject[256], inchar = ' ';
  49.     struct stat st;
  50.     time_t current;
  51.     long   secs, i, offset;
  52.     int    days;
  53.     int    no_space;
  54.     int    no_msgs;
  55.     int    subdone;
  56.     long   art_time;
  57.     long   where;
  58.  
  59.     FILE   *index;
  60.     FILE   *old_index;
  61.     FILE   *text;
  62.     FILE   *old_text;
  63.  
  64.     int    articles;
  65.     int    articles_deleted;
  66.     int    gp_art;
  67.     int    gp_art_deleted;
  68.  
  69.     long   total_bytes;
  70.     long   total_bytes_deleted;
  71.     long   gp_bytes;
  72.     long   gp_bytes_deleted;
  73.  
  74.  
  75.     articles = 0;
  76.     articles_deleted = 0;
  77.  
  78.     total_bytes = 0;
  79.     total_bytes_deleted = 0;
  80.  
  81.  
  82.   fprintf(stderr, "NEWSBASE EXPIRE\n%s\n\n", VERSION);
  83.  
  84.   if (argc == 2) {
  85.  
  86.      if (!load_stuff()) {
  87.         fprintf(stderr, "Couldn't read rc info\n");
  88.      }
  89.  
  90.      head = load_active_file();
  91.  
  92.      time(¤t);
  93.  
  94.      days = atoi(argv[1]);
  95.      secs = days * 86400l;
  96.  
  97.      gp = head;
  98.  
  99.      printf("NEWSGROUP                           :      ARTICLES         DELETED\n\n");
  100.  
  101.      while (gp != NULL) {
  102.  
  103.            no_space = FALSE;
  104.  
  105.            gp_art = 0;
  106.            gp_art_deleted = 0;
  107.            gp_bytes = 0;
  108.            gp_bytes_deleted = 0;
  109.  
  110.            if ((gp->hi_num - gp->lo_num) <= 0) {
  111.               printf("%-35s is empty. Next newsgroup.",gp->group);
  112.               no_msgs = TRUE;
  113.               inchar = 'e';
  114.               }
  115.  
  116.            if ((gp->hi_num - gp->lo_num) > 0) {
  117.                no_msgs = FALSE;
  118.                printf("%-35s, process it: ",gp->group);
  119.                inchar = getch();
  120.                if (inchar == 'y' || inchar == 'Y') {
  121.                 /*
  122.                  *  Open all the files.  First the old ones, then the new
  123.                  */
  124.                 fn = make_news_group_name(gp->group);
  125.  
  126.                 stat(fn, &st);
  127.                 gp_bytes_deleted = st.st_size;
  128.  
  129.                 if ((old_text = fopen(fn, "rb")) == NULL) crash("can't open old text", fn);
  130.                 setvbuf(old_text, NULL, _IOFBF, 16384);
  131.                 sprintf(buf, "%s.IDX", fn);
  132.                 if ((old_index = fopen(buf, "rb")) == NULL) crash("can't open old index", buf);
  133.  
  134.                 sprintf(buf, "%s.NEW", fn);
  135.                 if ((text = fopen(buf, "wb")) == NULL) crash("can't create new text", buf);
  136.                 setvbuf(text, NULL, _IOFBF, 16384);
  137.                 sprintf(buf, "%s.NDX", fn);
  138.                 if ((index = fopen(buf, "wb")) == NULL) crash("can't create new index", buf);
  139.  
  140.                 /* numbers go chronologically */
  141.                 for (i = (gp->lo_num)+1; i <= gp->hi_num; i++) {
  142.  
  143.                     fgets(buf, 255, old_index);
  144.                     if (i != atol(buf+9)) {
  145.                         fprintf(stderr, "\nsnews: article %ld found when %ld"
  146.                             " expected\n", atol(buf+9), i);
  147.                         exit(1);
  148.                     }
  149.  
  150.                     /* get the time the article was processed */
  151.                     art_time = atol(buf+18);
  152.  
  153.                     if ((current - art_time) > secs) {
  154.  
  155.                         /*
  156.                          *  Older than req'd - just count the totals
  157.                          */
  158.  
  159.                         gp_art_deleted++;
  160.  
  161.                         gp->lo_num++;
  162.                         update_active_entry(gp);
  163.  
  164.                     } else {
  165.  
  166.                         /*
  167.                          *  Younger than limit, so keep the article
  168.                          */
  169.                         subdone = FALSE;
  170.                         where = ftell(text);
  171.  
  172.                         /* copy to new file */
  173.                         offset = atol(buf);
  174.                         fseek(old_text, offset, SEEK_SET);
  175.                         while (fgets(buf, 255, old_text)) {
  176.  
  177.                             if ((strnicmp(buf,"Subject:",8) == 0) &&
  178.                  (subdone == FALSE)) {
  179.                                strcpy(subject, buf+8);
  180.                    subdone = TRUE;
  181.                             }
  182.  
  183.                             if (fputs(buf, text) == EOF) {
  184.                                 no_space = TRUE;
  185.                                 break;
  186.                             }
  187.                             if (strnicmp(buf, "@@@@END", 7) == 0) break;
  188.                         }
  189.  
  190.                         /* save the header info */
  191.                         fprintf(index,"%08ld %08ld %09ld %s", where, i,
  192.                             art_time, subject);
  193.                     }
  194.  
  195.                     if (no_space) break;
  196.                 }
  197.  
  198.                 /*
  199.                  *  Close and rename the files
  200.                  */
  201.  
  202.                 fclose(old_text);
  203.                 fclose(old_index);
  204.                 fclose(text);
  205.                 fclose(index);
  206.  
  207.  
  208.                 fn = make_news_group_name(gp->group);
  209.  
  210.                 /* out of disk on expire, delete the temp files */
  211.                 if (no_space) {
  212.                     fprintf(stderr, "expire: no room to expire %s\n", gp->group);
  213.                     sprintf(buf2, "%s.NEW", fn);
  214.                     unlink(buf2);
  215.                     sprintf(buf2, "%s.NDX", fn);
  216.                     unlink(buf2);
  217.                 } else {
  218.                     unlink(fn);
  219.                     sprintf(buf2, "%s.NEW", fn);
  220.                     stat(buf2, &st);
  221.                     gp_bytes = st.st_size;
  222.                     rename(buf2, fn);
  223.  
  224.                     sprintf(buf, "%s.IDX", fn);
  225.                     unlink(buf);
  226.                     sprintf(buf2, "%s.NDX", fn);
  227.                     rename(buf2, buf);
  228.                 }
  229.  
  230.                 /* print all groups with articles */
  231.  
  232.                 gp_art = (int)(gp->hi_num - gp->lo_num);
  233.                 gp_bytes_deleted -= gp_bytes;
  234.  
  235.                 articles += gp_art;
  236.                 articles_deleted += gp_art_deleted;
  237.                 total_bytes += gp_bytes;
  238.                 total_bytes_deleted += gp_bytes_deleted;
  239.  
  240.                 if ((gp_art > 0) || (gp_art_deleted > 0)) {
  241.  
  242.                     if (gp_art_deleted > 0)
  243.                         printf("\r%-35s :  %4d %5ldKb     %4d %5ldKb",
  244.                             gp->group,
  245.                             gp_art, (gp_bytes+500)/1000,
  246.                             gp_art_deleted, (gp_bytes_deleted+500)/1000);
  247.                     else
  248.                         printf("\r%-35s :  %4d %5ldKb",
  249.                             gp->group,
  250.                             gp_art, (gp_bytes+500)/1000);
  251.  
  252.                 }
  253.             }
  254.           } else { if (!no_msgs)
  255.                      printf("  Area skipped... Next area.");
  256.                      }
  257.             if (inchar != 'y' && inchar != 'Y' && inchar != 'q' && inchar != 'Q' && inchar != 'e')
  258.                 { printf("\r%-35s Area skipped...",gp->group);}
  259.             if (inchar == 'q' || inchar == 'Q') {
  260.                  printf("\r%-35s Area skipped... Quit requested.",gp->group);
  261.                  while (gp != NULL)
  262.                        gp = gp->next;}
  263.             else
  264.                 {gp = gp->next;}
  265.  
  266.             printf("\n");
  267.         }
  268.  
  269.         close_active_file();
  270.  
  271.         expire_history(current, secs);
  272.  
  273.         printf("\nOf the newsgroups that were altered:\n"
  274.                "\n%7d articles were deleted\n"
  275.                "%7ld Kb were deleted\n"
  276.                "%7d articles are remaining\n"
  277.                "%7ld Kb of text is remaining\n",
  278.                articles_deleted,
  279.                (total_bytes_deleted+500)/1000,
  280.                articles,
  281.                (total_bytes+500)/1000);
  282.  
  283.     } else {
  284.         fprintf(stderr, "usage:  expire <days>\n");
  285.     }
  286. }
  287.  
  288.  
  289. /*----------------------------------------------------------------------*/
  290. void crash(char *msg, char *fn)
  291. {
  292.     /*
  293.      *  Abort if file open error
  294.      */
  295.  
  296.     fprintf(stderr, "\nexpire: %s, %s\n", msg, fn);
  297.     exit(1);
  298. }
  299.  
  300.  
  301. /*--------------------------- expire history entries --------------------*/
  302. void expire_history(long current, long secs)
  303. {
  304.     FILE *hist_file, *new_hist_file;
  305.     long age;
  306.     char buf[512], buf2[256];
  307.  
  308.  
  309.     /* open the files */
  310.     sprintf(buf, "%shistory", my_stuff.news_dir);
  311.     if ((hist_file = fopen(buf, "rb")) == NULL) {
  312.         fprintf(stderr, "expire: cannot open file %s for input\n", buf);
  313.         exit(1);
  314.     }
  315.     sprintf(buf, "%shistory.new", my_stuff.news_dir);
  316.     if ((new_hist_file = fopen(buf, "wb")) == NULL) {
  317.         fprintf(stderr, "expire: cannot open file %s for output\n", buf);
  318.         exit(1);
  319.     }
  320.  
  321.     while (fgets(buf, 255, hist_file) != NULL) {
  322.         sscanf(buf, "%*s %ld", &age);
  323.         if ((current-age) < secs) {
  324.             fputs(buf, new_hist_file);
  325.         }
  326.     }
  327.  
  328.     fclose(hist_file);
  329.     fclose(new_hist_file);
  330.  
  331.     sprintf(buf, "%shistory.bak", my_stuff.news_dir);
  332.     unlink(buf);
  333.     sprintf(buf2, "%shistory", my_stuff.news_dir);
  334.     rename(buf2, buf);
  335.     sprintf(buf, "%shistory.new", my_stuff.news_dir);
  336.     rename(buf, buf2);
  337.     sprintf(buf, "%shistory.bak", my_stuff.news_dir);
  338.     unlink(buf);
  339.  
  340. }
  341.